mod db;
mod websocket;
mod http_server;
mod asset_server;
mod html_templates;

use db::{DbManager, Riddle, Game};
use std::sync::{Arc, Mutex};
use tauri::{State, Manager, Emitter};
use log::{info, error};
use serde::Deserialize;
use std::collections::HashMap;
use std::path::PathBuf;

// 获取所有游戏
#[tauri::command]
fn get_games(state: State<DbState>) -> Result<Vec<Game>, String> {
    let db_manager = state.manager.lock().unwrap();
    db_manager.get_games().map_err(|e| e.to_string())
}

// 获取未使用的谜语
#[tauri::command]
fn get_unused_riddles(
    state: State<DbState>,
    request: RiddleRequest,
) -> Result<Vec<Riddle>, String> {
    let db_manager = state.manager.lock().unwrap();
    if let Some(game_id) = request.game_id {
        db_manager.get_unused_riddles_by_game(game_id, request.count).map_err(|e| e.to_string())
    } else {
        db_manager.get_unused_riddles(request.count, request.type_.as_deref()).map_err(|e| e.to_string())
    }
}

// 标记谜语为已使用
#[tauri::command]
fn mark_riddle_as_used(
    state: State<DbState>,
    request: MarkUsedRequest,
) -> Result<(), String> {
    let db_manager = state.manager.lock().unwrap();
    if let Some(game_id) = request.game_id {
        db_manager.mark_riddle_as_used(request.id, Some(game_id)).map_err(|e| e.to_string())
    } else {
        db_manager.mark_riddle_as_used(request.id, None).map_err(|e| e.to_string())
    }
}

// 重置所有谜语使用状态
#[tauri::command]
fn reset_riddles(state: State<DbState>) -> Result<(), String> {
    let db_manager = state.manager.lock().unwrap();
    db_manager.reset_riddles().map_err(|e| e.to_string())
}

/// 数据库状态管理
#[derive(Clone)]
struct DbState {
    manager: Arc<Mutex<DbManager>>,
}

/// HTTP服务器状态管理
#[derive(Clone)]
struct HttpServerState {
    is_running: Arc<Mutex<bool>>,
}

/// WebSocket服务器状态管理
#[derive(Clone)]
struct WebSocketServerState {
    is_running: Arc<Mutex<bool>>,
}

// 谜语请求参数
#[derive(Deserialize)]
struct RiddleRequest {
    count: usize,
    type_: Option<String>,
    game_id: Option<i64>,
}

// 标记谜语为已使用的请求
#[derive(Deserialize)]
struct MarkUsedRequest {
    id: i64,
    game_id: Option<i64>,
}

// 游戏请求参数
#[derive(Deserialize)]
struct GameRequest {
    id: i64,
}

// WebSocket服务器状态 - 暂时保留用于未来扩展
#[allow(dead_code)]
struct WebSocketState {
    is_running: Arc<Mutex<bool>>,
}

// 启动Asset服务器（使用Tauri Asset Resolver）
#[tauri::command]
async fn start_asset_server(port: u16, app_handle: tauri::AppHandle) -> Result<String, String> {
    info!("启动Asset服务器，端口: {}", port);
    
    let app_handle_clone = app_handle.clone();
    tokio::spawn(async move {
        if let Err(e) = asset_server::start_asset_server(app_handle_clone, port).await {
            error!("Asset服务器启动失败: {}", e);
            // 发送错误事件
            let error_msg = format!("Asset服务器启动失败: {}", e);
            if let Err(emit_err) = app_handle.emit("asset_server_error", &error_msg) {
                error!("发送错误事件失败: {}", emit_err);
            }
        }
    });
    
    // 等待一小段时间确保服务器启动
    tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
    
    Ok(format!("Asset服务器已启动在端口 {}", port))
}

// 启动混合服务器（Asset Resolver + 文件系统）
#[tauri::command]
async fn start_hybrid_server(port: u16, static_dir: Option<String>, app_handle: tauri::AppHandle) -> Result<String, String> {
    info!("启动混合服务器，端口: {}", port);
    
    let fallback_dir = static_dir.map(|dir| {
        resolve_static_path(&dir, &app_handle)
    });
    
    let app_handle_clone = app_handle.clone();
    tokio::spawn(async move {
        if let Err(e) = asset_server::start_hybrid_server(app_handle_clone, port, fallback_dir).await {
            error!("混合服务器启动失败: {}", e);
            // 发送错误事件
            let error_msg = format!("混合服务器启动失败: {}", e);
            if let Err(emit_err) = app_handle.emit("hybrid_server_error", &error_msg) {
                error!("发送错误事件失败: {}", emit_err);
            }
        }
    });
    
    // 等待一小段时间确保服务器启动
    tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
    
    Ok(format!("混合服务器已启动在端口 {}", port))
}


// 解析静态资源路径
fn resolve_static_path(static_dir: &str, app_handle: &tauri::AppHandle) -> PathBuf {
    // 如果是绝对路径，直接使用
    let path = PathBuf::from(static_dir);
    if path.is_absolute() {
        return path;
    }
    
    // 相对路径处理
    if cfg!(debug_assertions) {
        // 开发模式：相对于项目根目录
        let current_dir = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
        current_dir.join(static_dir)
    } else {
        // 生产模式：优先尝试资源目录
        if let Ok(resource_dir) = app_handle.path().resource_dir() {
            let resource_path = resource_dir.join(static_dir);
            if resource_path.exists() {
                return resource_path;
            }
        }
        
        // 如果资源目录不存在，尝试应用数据目录
        let app_dir = app_handle.path().app_data_dir().unwrap_or_default();
        app_dir.join(static_dir)
    }
}

// 获取所有可能的静态资源路径
fn get_possible_static_paths(app_handle: &tauri::AppHandle) -> Vec<PathBuf> {
    let mut paths = Vec::new();
    
    // 1. 资源目录中的各种可能路径
    if let Ok(resource_dir) = app_handle.path().resource_dir() {
        info!("资源目录: {:?}", resource_dir);
        paths.push(resource_dir.join("dist"));
        paths.push(resource_dir.join("assets"));
        paths.push(resource_dir.clone()); // 资源可能直接在资源目录中
        
        // Android APK 特殊路径
        paths.push(resource_dir.join("www"));
        paths.push(resource_dir.join("public"));
    }
    
    // 2. 应用数据目录中的各种可能路径
    if let Ok(app_dir) = app_handle.path().app_data_dir() {
        info!("应用数据目录: {:?}", app_dir);
        paths.push(app_dir.join("dist"));
        paths.push(app_dir.join("static"));
        paths.push(app_dir.join("assets"));
        paths.push(app_dir.join("www"));
    }
    
    // 3. 应用本地数据目录
    if let Ok(local_data_dir) = app_handle.path().app_local_data_dir() {
        info!("本地数据目录: {:?}", local_data_dir);
        paths.push(local_data_dir.join("dist"));
        paths.push(local_data_dir.join("static"));
    }
    
    // 4. 当前工作目录中的dist（开发模式）
    if let Ok(current_dir) = std::env::current_dir() {
        info!("当前工作目录: {:?}", current_dir);
        paths.push(current_dir.join("dist"));
        // 移除可能导致路径混乱的 src-tauri/dist 路径
        // paths.push(current_dir.join("src-tauri").join("dist"));
        paths.push(current_dir.join("target").join("dist"));
    }
    
    // 5. 可执行文件目录
    if let Ok(exe_dir) = app_handle.path().app_data_dir() {
        info!("可执行文件目录: {:?}", exe_dir);
        paths.push(exe_dir.join("dist"));
        paths.push(exe_dir.join("assets"));
    }
    
    // 记录所有尝试的路径
    for (i, path) in paths.iter().enumerate() {
        info!("路径 {}: {:?} (存在: {})", i + 1, path, path.exists());
        if path.exists() {
            if let Ok(entries) = std::fs::read_dir(path) {
                let files: Vec<String> = entries
                    .filter_map(|e| e.ok())
                    .map(|e| e.file_name().to_string_lossy().to_string())
                    .collect();
                info!("  包含文件: {:?}", files);
            }
        }
    }
    
    paths
}

// 启动WebSocket服务器
#[tauri::command]
async fn start_websocket_server(port: u16, websocket_state: State<'_, WebSocketServerState>, app_handle: tauri::AppHandle) -> Result<String, String> {
    info!("启动WebSocket服务器，端口: {}", port);
    
    // 检查服务器是否已经在运行
    {
        let is_running = websocket_state.is_running.lock().unwrap();
        if *is_running {
            info!("WebSocket服务器已经在运行，跳过启动");
            return Ok("WebSocket服务器已经在运行".to_string());
        }
    }
    
    // 标记服务器正在启动
    {
        let mut is_running = websocket_state.is_running.lock().unwrap();
        *is_running = true;
    }
    
    let websocket_state_clone = websocket_state.inner().clone();
    let app_handle_clone = app_handle.clone();
    
    tokio::spawn(async move {
        if let Err(e) = websocket::start_websocket_server(port).await {
            error!("WebSocket服务器启动失败: {}", e);
            // 如果启动失败，重置状态
            let mut is_running = websocket_state_clone.is_running.lock().unwrap();
            *is_running = false;
            // 发送错误事件
            let error_msg = format!("WebSocket服务器启动失败: {}", e);
            if let Err(emit_err) = app_handle_clone.emit("websocket_server_error", &error_msg) {
                error!("发送错误事件失败: {}", emit_err);
            }
        }
    });
    
    // 等待一小段时间确保服务器启动
    tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
    
    Ok(format!("WebSocket服务器已启动在端口 {}", port))
}

// 重置WebSocket服务器状态
#[tauri::command]
fn reset_websocket_server_status(websocket_state: State<WebSocketServerState>) -> Result<String, String> {
    info!("重置WebSocket服务器状态");
    let mut is_running = websocket_state.is_running.lock().unwrap();
    *is_running = false;
    Ok("WebSocket服务器状态已重置".to_string())
}

// 获取本地IP地址
#[tauri::command]
fn get_local_ip() -> Result<String, String> {
    match get_local_ip_internal() {
        Ok(ip) => Ok(ip.to_string()),
        Err(e) => {
            error!("获取本地IP失败: {}", e);
            Err(format!("获取本地IP失败: {}", e))
        }
    }
}

// 检查HTTP服务器状态
#[tauri::command]
fn check_http_server_status(http_state: State<HttpServerState>) -> bool {
    let is_running = http_state.is_running.lock().unwrap();
    *is_running
}

// 检查WebSocket服务器状态
#[tauri::command]
fn check_websocket_server_status(websocket_state: State<WebSocketServerState>) -> bool {
    let is_running = websocket_state.is_running.lock().unwrap();
    *is_running
}

// 获取本地IP地址的内部实现
fn get_local_ip_internal() -> Result<std::net::IpAddr, Box<dyn std::error::Error>> {
    match local_ip_address::local_ip() {
        Ok(ip) => Ok(ip),
        Err(e) => Err(Box::new(e))
    }
}

// 获取所有游戏
#[tauri::command]
async fn start_http_server(port: u16, _app_handle: tauri::AppHandle) -> Result<String, String> {
    use log::info;

    info!("启动HTTP服务器，端口: {}", port);

    tokio::spawn(async move {
        use warp::Filter;
        use urlencoding::encode;

        // 创建根路径路由，返回重定向到移动端绘图页面的HTML
        let index_route = warp::path::end().and(warp::query::raw()).map(|query: String| {
            let redirect_url = if query.is_empty() {
                "/#/drawguess".to_string()
            } else {
                // 清理查询字符串：移除开头的?字符（如果有）
                let clean_query = if query.starts_with('?') {
                    query[1..].to_string()
                } else {
                    query
                };
                
                // 如果查询字符串已经包含编码字符，避免双重编码
                let processed_query = if clean_query.contains('%') {
                    // 假设查询字符串已经被编码，直接使用
                    clean_query
                } else {
                    // 对原始查询字符串进行编码
                    encode(&clean_query).to_string()
                };
                format!("/#/drawguess?{}", processed_query)
            };
            warp::reply::html(html_templates::mobile_redirect_html(&redirect_url))
        });

        let routes = index_route;

        let addr = ([0, 0, 0, 0], port);
        warp::serve(routes).run(addr).await;
    });

    tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;

    Ok(format!("HTTP服务器已启动在端口 {}", port))
}

// 重置特定游戏的谜语使用状态
#[tauri::command]
fn reset_riddles_by_game(
    state: State<DbState>,
    request: GameRequest,
) -> Result<(), String> {
    let db_manager = state.manager.lock().unwrap();
    db_manager.reset_riddles_by_game(request.id).map_err(|e| e.to_string())
}

// 获取单个设置
#[tauri::command]
fn get_setting(
    state: State<DbState>,
    key: String,
) -> Result<Option<String>, String> {
    let db_manager = state.manager.lock().unwrap();
    db_manager.get_setting(&key).map_err(|e| e.to_string())
}

// 获取所有设置
#[tauri::command]
fn get_all_settings(
    state: State<DbState>,
) -> Result<HashMap<String, String>, String> {
    let db_manager = state.manager.lock().unwrap();
    db_manager.get_all_settings().map_err(|e| e.to_string())
}

// 更新单个设置
#[tauri::command]
fn update_setting(
    state: State<DbState>,
    key: String,
    value: String,
) -> Result<(), String> {
    let mut db_manager = state.manager.lock().unwrap();
    db_manager.update_setting(&key, &value).map_err(|e| e.to_string())
}

// 批量更新设置
#[tauri::command]
fn update_settings(
    state: State<DbState>,
    settings: HashMap<String, String>,
) -> Result<(), String> {
    let mut db_manager = state.manager.lock().unwrap();
    db_manager.update_settings(&settings).map_err(|e| e.to_string())
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
  tauri::Builder::default()

    .setup(|app| {
      if cfg!(debug_assertions) {
        app.handle().plugin(
          tauri_plugin_log::Builder::default()
            .level(log::LevelFilter::Info)
            .build(),
        )?;
      }
      
      // 初始化数据库
      let app_dir = app.path().app_data_dir()?;
      let db_path = app_dir.join("riddles.db");
      
      // 确保目录存在
      if !app_dir.exists() {
          std::fs::create_dir_all(&app_dir)?;
      }
      
      
      info!("Database path: {:?}", db_path);
      
      // 创建数据库管理器
      let db_manager = match DbManager::new(db_path.to_str().unwrap()) {
          Ok(manager) => manager,
          Err(e) => {
              error!("Failed to initialize database: {}", e);
              return Err(e.into());
          }
      };
      
      // 创建HTTP服务器状态
      let http_server_state = HttpServerState {
        is_running: Arc::new(Mutex::new(false)),
      };
      
      // 创建WebSocket服务器状态
      let websocket_server_state = WebSocketServerState {
        is_running: Arc::new(Mutex::new(false)),
      };
      
      // 将数据库管理器添加到应用状态
      app.manage(DbState {
          manager: Arc::new(Mutex::new(db_manager)),
      });
      app.manage(http_server_state);
      app.manage(websocket_server_state);
      
      Ok(())
    })
    .on_window_event(|window, event| {
      match event {
        tauri::WindowEvent::Focused(true) => {
          // 窗口获得焦点时启动HTTP和WebSocket服务器（仅启动一次）
          let http_state = window.state::<HttpServerState>();
          let websocket_state = window.state::<WebSocketServerState>();
          let app_handle = window.app_handle().clone();
          
          // 检查HTTP服务器是否已经在运行
          let should_start_http = {
            let is_running = http_state.is_running.lock().unwrap();
            !*is_running
          };
          
          // 检查WebSocket服务器是否已经在运行
          let should_start_websocket = {
            let is_running = websocket_state.is_running.lock().unwrap();
            !*is_running
          };
          
          if !should_start_http && !should_start_websocket {
            info!("HTTP和WebSocket服务器都已经在运行，跳过启动");
            return;
          }
          
          // 启动HTTP服务器
          if should_start_http {
            let http_state_clone = http_state.inner().clone();
            let app_handle_clone = app_handle.clone();
            tauri::async_runtime::spawn(async move {
              // 标记服务器正在启动
              {
                let mut is_running = http_state_clone.is_running.lock().unwrap();
                *is_running = true;
              }
              
              info!("启动HTTP服务器，端口: 3030");

          if let Err(e) = http_server::start_http_server(3030).await {
              error!("启动HTTP服务器失败: {}", e);
              // 如果启动失败，重置状态
              let mut is_running = http_state_clone.is_running.lock().unwrap();
              *is_running = false;
              // 发送弹窗通知
              let error_msg = format!("HTTP服务器启动失败: {}", e);
              if let Err(emit_err) = app_handle_clone.emit("http_server_error", &error_msg) {
                  error!("发送错误事件失败: {}", emit_err);
              }
          }
            });
          }
          
          // 启动WebSocket服务器
          if should_start_websocket {
            let websocket_state_clone = websocket_state.inner().clone();
            let app_handle_clone = app_handle.clone();
            tauri::async_runtime::spawn(async move {
              // 标记服务器正在启动
              {
                let mut is_running = websocket_state_clone.is_running.lock().unwrap();
                *is_running = true;
              }
              
              info!("启动WebSocket服务器，端口: 3032");
              if let Err(e) = websocket::start_websocket_server(3032).await {
                error!("启动WebSocket服务器失败: {}", e);
                // 如果启动失败，重置状态
                let mut is_running = websocket_state_clone.is_running.lock().unwrap();
                *is_running = false;
                // 发送弹窗通知
                let error_msg = format!("WebSocket服务器启动失败: {}", e);
                if let Err(emit_err) = app_handle_clone.emit("websocket_server_error", &error_msg) {
                  error!("发送错误事件失败: {}", emit_err);
                }
              }
            });
          }
        }
        _ => {}
      }
    })
    .invoke_handler(tauri::generate_handler![
        get_games,
        get_unused_riddles,
        mark_riddle_as_used,
        reset_riddles,
        reset_riddles_by_game,
        get_setting,
        get_all_settings,
        update_setting,
        update_settings,
        start_websocket_server,
        start_http_server,
        start_asset_server,
        start_hybrid_server,
        get_local_ip,
        check_http_server_status,
        check_websocket_server_status,
        reset_websocket_server_status
    ])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}
